﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using ArduinoSketch.Core;

namespace ArduinoSketch
{
    public partial class frmMain : Form
    {
        private Sketch _sketch;
        private ITerminal _serialMonitor;
        private ISolutionExplorer _solution ;
        private frmOutput _output;
        private LibraryFactory _libraryFactory;

        public frmMain()
        {
            InitializeComponent();
            this._sketch = new Sketch(this, dockPanel);
            this._sketch.OnProjectSelected += new EventHandler<ProjectSelectedArgs>(_documentMenager_OnProjectSelected);
            this._libraryFactory = new LibraryFactory();
            this._libraryFactory.BuildLibrary();
            this.CreateLibraryMenu();
            this.CreateContents();

            Compiler.EndCompile = new EndCompileAsync(DoEndCompile);
            Compiler.BeginCompile = new BeginCompileAsync(DoBeginCompile);
            Compiler.Compiling = new CompilingAsync(DoCompiling);
        }

        private void DoCompiling(int progress)
        {
            statusProgress.Value = progress;
        }

        private void DoEndCompile()
        {
            lbCurrentProject.Visible = true;
            statusProgress.Visible = false ;
        }

        private void DoBeginCompile()
        {
            lbCurrentProject.Visible = false;
            statusProgress.Value = 0;
            statusProgress.Visible = true;
        }

        void _documentMenager_OnProjectSelected(object sender, ProjectSelectedArgs e)
        {
            if (e.Project != null)
            {
                this.lbCurrentProject.Text = "Project Selected: " + e.Project.ProjectName;
                this.lbBoard.Text = "Board: " + e.Project.HardwareProfile;
            }
        }

        private void CreateLibraryMenu()
        {
            sketchLibrary.DropDownItems.Clear();
            foreach (var lib in _libraryFactory.Library)
            {
                RibbonButton _btn = new RibbonButton();
                _btn.Click += new EventHandler(_btn_Click);
                sketchLibrary.DropDownItems.Add(_btn);
                _btn.Text = lib.Key;
                _btn.Tag = lib.Value;
            }

            LoadComportName();
        }

        private void LoadComportName()
        {
            string[] strArray = ArduinoSketch.Core.DeviceInfo.ParseFriendlyPorts();
            sketchSerialPort.DropDownItems.Clear();
            int _idx = 0;
            foreach (string strPort in strArray)
            {
                if (!String.IsNullOrEmpty(strPort))
                {
                    RibbonButton _btnPort = new RibbonButton();
                    _btnPort.Text = strPort;
                    _btnPort.Tag = _idx;
                    _btnPort.Click += new EventHandler(_btnPort_Click);
                    sketchSerialPort.DropDownItems.Add(_btnPort);
                    _idx++;
                }
            }
        }

        void _btnPort_Click(object sender, EventArgs e)
        {
            RibbonButton _btn = sender as RibbonButton;
            int _idx = int.Parse(_btn.Tag.ToString());
            string[] strArray = DeviceInfo.ParsePorts();

            if (strArray[_idx] != "")
            {
                string SelectedPort = strArray[_idx];
                lbPort.Text = "Selected Port: " + SelectedPort;
                _sketch.SetCrrentUploadPort(SelectedPort);
            }
        }

        void _btn_Click(object sender, EventArgs e)
        {
            RibbonButton _btn = sender as RibbonButton;
            _sketch.AddLibrary((Library)_btn.Tag);
        }

        private void CreateContents()
        {
            _output = new frmOutput();
            _output.Show(dockPanel, WeifenLuo.WinFormsUI.Docking.DockState.DockBottomAutoHide);

            _solution = new frmSolution();
            _solution.OnToolNewExternalFileClick += new EventHandler(_solution_OnToolNewExternalFileClick);
            _solution.OnToolNewHeaderFileClick += new EventHandler(_solution_OnToolNewHeaderFileClick);
            _solution.OnToolNewProjectClick += new EventHandler(_solution_OnToolNewProjectClick);
            _solution.OnToolNewSolutionClick += new EventHandler(_solution_OnToolNewSolutionClick);
            _solution.OnToolNewSourceFileClick += new EventHandler(_solution_OnToolNewSourceFileClick);
            _solution.OnToolRemoveFileClick += new EventHandler(_solution_OnToolRemoveFileClick);
            _solution.OnToolRemoveProjectClick += new EventHandler(_solution_OnToolRemoveProjectClick);
            _solution.OnToolExistingProjectClick += new EventHandler(_solution_OnToolExistingProjectClick);
            ((frmSolution)_solution).Show(dockPanel, WeifenLuo.WinFormsUI.Docking.DockState.DockLeft);

            _sketch.AttachSolutionExplorer(_solution);
            _sketch.AttachOutputConsole(_output);

        }

        public void _solution_OnToolExistingProjectClick(object sender, EventArgs e)
        {
            _sketch.AddExistingProject();
        }

        private void _solution_OnToolRemoveProjectClick(object sender, EventArgs e)
        {
            _sketch.RemoveSketch();
        }

        private void _solution_OnToolRemoveFileClick(object sender, EventArgs e)
        {
            string _fileName = "";
            _fileName = _solution.SelectedFileName;
            if (!String.IsNullOrEmpty(_fileName))
                _sketch.RemoveFileFormSketch(_fileName);
        }

        private void _solution_OnToolNewSourceFileClick(object sender, EventArgs e)
        {
            _sketch.NewFileToSketch(NewFileType.SOURCE_FILE);
        }

        private void _solution_OnToolNewSolutionClick(object sender, EventArgs e)
        {
            _sketch.CloseSolution();
            _sketch.NewSketch();
        }

        private void _solution_OnToolNewProjectClick(object sender, EventArgs e)
        {
            _sketch.NewSketch();
        }

        private void _solution_OnToolNewHeaderFileClick(object sender, EventArgs e)
        {
            _sketch.NewFileToSketch(NewFileType.HEADER_FILE);
        }

        private void _solution_OnToolNewExternalFileClick(object sender, EventArgs e)
        {
            if (this.openFileDialog.ShowDialog() == DialogResult.OK)
            {
                this._sketch.AddFileToSketch(this.openFileDialog.FileName);
            }
        }
 
        #region File Menu Helper
        private void fileNew_Click(object sender, EventArgs e)
        {
            _sketch.New();
        }

        private void fileOpen_Click(object sender, EventArgs e)
        {
            _sketch.Open();
        }

        private void fileSave_Click(object sender, EventArgs e)
        {
            _sketch.Save();
        }

        private void fileSaveAs_Click(object sender, EventArgs e)
        {
            _sketch.SaveAs();
        }
        #endregion

        #region Edit Menu Helper
        private void editCut_Click(object sender, EventArgs e)
        {
            _sketch.Cut();
        }

        private void editCoppy_Click(object sender, EventArgs e)
        {
            _sketch.Coppy();
        }

        private void editPaste_Click(object sender, EventArgs e)
        {
            _sketch.Paste();
        }

        private void editUndo_Click(object sender, EventArgs e)
        {
            _sketch.Undo();
        }

        private void editRedo_Click(object sender, EventArgs e)
        {
            _sketch.Redo();
        }

        private void editFind_Click(object sender, EventArgs e)
        {
            _sketch.Find();
        }

        private void editReplace_Click(object sender, EventArgs e)
        {
            _sketch.Replace();
        }

        private void editClearBookmarks_Click(object sender, EventArgs e)
        {
            _sketch.ClearBookmars();
        }

        private void editToggleBookmark_Click(object sender, EventArgs e)
        {
            _sketch.ToggleBookmark();
        }

        private void editPreviousBookmark_Click(object sender, EventArgs e)
        {
            _sketch.PreviosBookmark();
        }

        private void editNextBookmark_Click(object sender, EventArgs e)
        {
            _sketch.NextBookmark();
        }
        #endregion

        #region Sketch Menu Helper
        private void sketchNew_Click(object sender, EventArgs e)
        {
            _sketch.NewSketch();
        }

        private void sketchOpen_Click(object sender, EventArgs e)
        {
            _sketch.OpenSketch();
        }

        private void sketchSave_Click(object sender, EventArgs e)
        {
            _sketch.SaveSketch();
        }

        private void sketchSaveAs_Click(object sender, EventArgs e)
        {
            _sketch.SaveSketchAs();
        }

        private void sketchCompile_Click(object sender, EventArgs e)
        {
            _sketch.Compile();
        }

        private void sketchUpload_Click(object sender, EventArgs e)
        {
            if (_serialMonitor != null)
            {
                if (_serialMonitor.IsPortOpen())
                    _serialMonitor.CloaePort();
            }

            _sketch.Upload();
        }

        private void skethSaveAll_Click(object sender, EventArgs e)
        {
            _sketch.SaveAll();
        }

        private void sketchLibrary_Click(object sender, EventArgs e)
        {
            _libraryFactory.BuildLibrary();
            this.CreateLibraryMenu();
        }

        private void sketchProperties_Click(object sender, EventArgs e)
        {
            _sketch.SketchProperies();
        }

        private void sketchClose_Click(object sender, EventArgs e)
        {
            this._sketch.CloseSolution();
            this.lbCurrentProject.Text = "Emtry Project";
            this.lbBoard.Text = "Board : ";
            this.lbPort.Text = "Select Port :  Not Selected";
        }

        #endregion

        private void toolArduinoSetting_Click(object sender, EventArgs e)
        {
            ArduioSetting _arduioSetting = new ArduioSetting();
            _arduioSetting.ShowDialog();
            _arduioSetting.Dispose();
            GC.SuppressFinalize(_arduioSetting);
        }

        private void sketchSerialPort_Click(object sender, EventArgs e)
        {
            this.LoadComportName();
        }

        #region Serial Monitor
        private void toolSerial_Click(object sender, EventArgs e)
        {
            bool _isActivate = false;

            foreach (var documentForm in dockPanel.Documents)
            {
                if (documentForm is SerialMonitor)
                {
                    ((SerialMonitor)documentForm).Activate(); 
                    ((SerialMonitor)documentForm).Select();
                    _isActivate = true;
                }
            }

            if (!_isActivate)
            {
                _serialMonitor = new SerialMonitor();
                ((SerialMonitor)_serialMonitor).Show(this.dockPanel, WeifenLuo.WinFormsUI.Docking.DockState.Document);
            }
        }

        private void serialSetting_Click(object sender, EventArgs e)
        {
            
            if (_serialMonitor != null)
                _serialMonitor.PortPropertiesSetting();
        }

        private void serialOpen_Click(object sender, EventArgs e)
        {
            if (_serialMonitor != null)
                _serialMonitor.OpenPort();
        }

        private void serialClose_Click(object sender, EventArgs e)
        {
            if (_serialMonitor != null)
                _serialMonitor.CloaePort();
        }

        private void serialClearReceiveText_Click(object sender, EventArgs e)
        {
            if (_serialMonitor != null)
                _serialMonitor.ClearReceiveText();
        }
        #endregion

        private void viewZoomIn_Click(object sender, EventArgs e)
        {
            _sketch.ZoomIn();
        }

        private void viewZoomOut_Click(object sender, EventArgs e)
        {
            _sketch.ZoomOut();
        }

        private void optApplicationExit_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }
    }
}
